import pandas as pd
import os, json
from pymongo import MongoClient
from aluminum_roll9 import generate_a_schedule,assign_discard_aluminum_tasks,assign_changsha_aluminum_roll_tasks
from aluminum_rod9 import assign_early_aluminum_rod_tasks,assign_late_aluminum_rod_tasks
from mongo_database9 import update_mongodb
from double_zero9 import double_zero_tasks
from single_top9 import single_top_tasks_morning,single_top_tasks_afternoon
from al_rool_morning9 import al_rool_morning
from jieche_changde9 import jieche_changde_tasks
from tools9 import calculate_rest_car_count, time_to_minutes, calculate_load_time, calculate_start_time, plan_to_result



def create_plan(today_tasks):
    # ----------------------
    # MongoDB数据加载
    # ----------------------
    MONGO_URI = "mongodb://172.40.10.141:27017/"
    DB_NAME = "innerVehicle"
    VEH_COLL = "vehicle_test"
    DRV_COLL = "driver_test"
    client = MongoClient(MONGO_URI)
    db_update = client[DB_NAME]
    collection_driver = db_update[DRV_COLL]
    collection_vehicle = db_update[VEH_COLL]

    # ----------------------
    # 计算休息车辆数量
    # ----------------------
    car_count_list=calculate_rest_car_count(collection_vehicle, today_tasks['休息车辆']['rest_car_numbers'])


    # ----------------------
    # 初始化车辆
    # ----------------------
    vehicles = []
    for i in range(8-int(car_count_list[0]['rest_count'])):
        vehicles.append({'id': f'S{i + 1}', 'type': 'SCANIA', 'available_time': -540, 'used': False})
    for i in range(2-int(car_count_list[1]['rest_count'])):
        vehicles.append({'id': f'B{i + 1}', 'type': '奔驰', 'available_time': -540, 'used': False})
    for i in range(3-int(car_count_list[2]['rest_count'])):
        vehicles.append({'id': f'J{i + 1}', 'type': '解放', 'available_time': -540, 'used': False})
    van_vehicles = []
    for i in range(3-int(car_count_list[3]['rest_count'])):
        van = {'id': f'X{i + 1}', 'type': '厢车', 'available_time': -540, 'used': False}
        vehicles.append(van)
        van_vehicles.append(van)


    # ----------------------
    # 初始化任务（不含铝卷）
    # ----------------------
    tasks = []
    for i in range(today_tasks['废铝卷']['count']):
        if i<2:
            if i<today_tasks['废铝卷']['scania']:
                tasks.append({'type': '废铝/铝卷', 'time': '7:00', 'car_type': 'SCANIA'})
            else:
                tasks.append({'type': '废铝/铝卷', 'time': '7:00', 'car_type': '奔驰'})
        else:
            if i < today_tasks['废铝卷']['scania']:
                tasks.append({'type': '废铝/铝卷', 'time': '8:30', 'car_type': 'SCANIA'})
            else:
                tasks.append({'type': '废铝/铝卷', 'time': '8:30', 'car_type': '奔驰'})
    for i in range(today_tasks['双零箔']['count']):
        if i<today_tasks['双零箔']['four_point_two']:
            tasks.append({'type': '双零箔', 'time': today_tasks['双零箔']['load_time'],'car_type': '厢车'})
        else:
            tasks.append({'type': '双零箔', 'time': today_tasks['双零箔']['load_time'], 'car_type': '解放'})
    for time in today_tasks['单顶']['load_times']:
        tasks.append({'type': '单顶', 'time': time if time[0] != '0' else time[1:]})
    for time in today_tasks['铝棒']['load_times']:
        tasks.append({'type': '铝棒', 'time': time if time[0] != '0' else time[1:]})


    # ----------------------
    # 货物废铝卷、双零箔、单顶、铝棒、铝卷，安排车辆
    # ----------------------
    schedule = []
    for i in range(len(tasks)):
        task = tasks[i]
        task_time_str = task['time']
        task_time = time_to_minutes(task_time_str)
        selected = None

        if task['type'] == '废铝/铝卷':
            j_candidates = [v for v in vehicles if v['type'] == task['car_type'] and v['available_time'] + 540 <= task_time]
            selected = j_candidates[0] if j_candidates else None
            if selected:
                schedule.append({
                    'driver_name': '', 'plate_number': '', 'vehicle_id': selected['id'],
                    'vehicle_type': selected['type'], 'departure_time': task_time_str,
                    'load_time': calculate_load_time(task_time_str,task['type']), 'cargo_type': task['type'],
                    'is_transfer': '否'
                })
                selected['available_time'] = time_to_minutes('24:00')
                selected['used'] = True
            else:
                print('时间为',task['time'],'的',task['type'],'无车辆可安排')

        if task['type'] == '双零箔':
            j_candidates = [v for v in vehicles if v['type'] == task['car_type'] and v['available_time'] + 540 <= task_time]
            selected = j_candidates[0] if j_candidates else None
            if not selected:
                scania_benz = [v for v in vehicles if
                               v['type'] in ['SCANIA', '奔驰'] and v['available_time'] + 540 <= task_time]
                selected = scania_benz[0] if scania_benz else None
            if selected:
                schedule.append({
                    'driver_name': '', 'plate_number': '', 'vehicle_id': selected['id'],
                    'vehicle_type': selected['type'], 'departure_time': calculate_start_time(task_time_str, task['type']),
                    'load_time': task_time_str, 'cargo_type': task['type'],
                    'is_transfer': '否'
                })
                selected['available_time'] = time_to_minutes('24:00')
                selected['used'] = True
            else:
                print('时间为',task['time'],'的',task['type'],'无车辆可安排')

        if task['type'] in ['铝棒', '单顶']:
            j_candidates = [v for v in vehicles if v['type'] == '解放' and v['available_time'] + 540 <= task_time]
            selected = j_candidates[0] if j_candidates else None
            if not selected:
                scania_benz = [v for v in vehicles if
                               v['type'] in ['奔驰'] and v['available_time'] + 540 <= task_time]
                selected = scania_benz[0] if scania_benz else None
            if not selected:
                scania_benz = [v for v in vehicles if
                               v['type'] in ['SCANIA'] and v['available_time'] + 540 <= task_time]
                selected = scania_benz[0] if scania_benz else None
            if selected:
                schedule.append({
                    'driver_name': '', 'plate_number': '', 'vehicle_id': selected['id'],
                    'vehicle_type': selected['type'], 'departure_time': calculate_start_time(task_time_str,task['type']),
                    'load_time': task_time_str, 'cargo_type': task['type'],
                    'is_transfer': '否'
                })
                if task['type'] == '铝棒':
                    selected['available_time'] = time_to_minutes(schedule[-1]['load_time'])
                else:
                    selected['available_time'] = time_to_minutes('24:00')
                selected['used'] = True
            else:
                print('时间为',task['time'],'的',task['type'],'无车辆可安排')


    # ----------------------
    # 处理剩余铝卷任务
    # ----------------------
    schedule = generate_a_schedule(today_tasks, schedule, vehicles)


    # ----------------------
    # 更新接车状态
    # ----------------------
    vehicle_trips = {}
    for item in schedule:
        vid = item['vehicle_id']
        vehicle_trips[vid] = vehicle_trips.get(vid, 0) + 1
    for item in schedule:
        if vehicle_trips[item['vehicle_id']] >= 2:
            item['is_transfer'] = '是'


    # ----------------------
    # 合并所有任务并排序
    # ----------------------
    all_tasks = schedule
    # all_tasks.sort(key=lambda x: time_to_minutes(x['departure_time']) if x['departure_time'] else float('inf'))

    # ----------------------
    # 转换为DataFrame并保存为CSV
    # ----------------------
    df = pd.DataFrame(all_tasks)
    df = df[['driver_name', 'plate_number', 'vehicle_id', 'vehicle_type', 'departure_time', 'load_time', 'cargo_type',
             'is_transfer']]
    df.to_csv('今日运输任务调度总表.csv', index=False, encoding='utf-8-sig')
    print("今日计划排班任务表")
    print(df)

    # ----------------------
    # MongoDB数据加载
    # ----------------------
    db = client[DB_NAME]
    db_update = client[DB_NAME]
    collection = db_update['driver_test']
    update_mongodb(collection)


    # 让休息人员,甩挂人员不参与后续任何任务分配
    assigned_drivers = set(today_tasks['休息人员名单']['rest_names'])
    assigned_drivers.add(str(today_tasks['常德甩挂人员']['name']))
    assigned_drivers.add(str(today_tasks['长沙甩挂人员']['name']))
    vehicle_docs = list(db[VEH_COLL].find({}, {"_id": 0}))
    driver_docs = list(db[DRV_COLL].find({}, {"_id": 0}))
    vehicle_df = pd.DataFrame(vehicle_docs)
    driver_df = pd.DataFrame(driver_docs)
    assigned_vehicles = set(vehicle_df[
                                vehicle_df['plate_number'].isin(today_tasks['休息车辆']['rest_car_numbers'])
                            ]['vehicle_id'])
    changde_result_df, assigned_vehicles, assigned_drivers, df1 = jieche_changde_tasks(df, driver_df, vehicle_df,
                                                                                       assigned_vehicles,
                                                                                       assigned_drivers)
    df = df[~(df["vehicle_id"].isin(df1["vehicle_id"]))]

    single_top_morning_result_df, assigned_vehicles, assigned_drivers = single_top_tasks_morning(df, driver_df,
                                                                                                 vehicle_df,
                                                                                                 assigned_vehicles,
                                                                                                 assigned_drivers)

    single_top_afternoon_result_df, assigned_vehicles, assigned_drivers = single_top_tasks_afternoon(df, driver_df,
                                                                                                     vehicle_df,
                                                                                                     assigned_vehicles,
                                                                                                     assigned_drivers)

    double_zero_results, assigned_vehicles, assigned_drivers = double_zero_tasks(df, today_tasks, driver_df, vehicle_df,
                                                                                 assigned_vehicles, assigned_drivers)
    al_rool_morning_results, df, assigned_drivers, assigned_vehicles = al_rool_morning(df, driver_df, vehicle_df,
                                                                                       assigned_vehicles,
                                                                                       assigned_drivers)

    early_aluminum_rod_results, assigned_drivers, assigned_vehicles, df = assign_early_aluminum_rod_tasks(df,
                                                                                                          vehicle_df,
                                                                                                          driver_df,
                                                                                                          assigned_drivers,
                                                                                                          assigned_vehicles)

    discard_aluminum_results, assigned_drivers, assigned_vehicles = assign_discard_aluminum_tasks(df, vehicle_df,
                                                                                                  driver_df,
                                                                                                  assigned_drivers,
                                                                                                  assigned_vehicles)


    late_aluminum_rod_results, assigned_drivers, assigned_vehicles = assign_late_aluminum_rod_tasks(df, vehicle_df,
                                                                                                    driver_df,
                                                                                                    assigned_drivers,
                                                                                                    assigned_vehicles)
    changsha_aluminum_roll_results, assigned_drivers = assign_changsha_aluminum_roll_tasks(df, driver_df,
                                                                                           assigned_drivers)
    time_plan_df = pd.DataFrame(changde_result_df + single_top_morning_result_df + single_top_afternoon_result_df +
                                double_zero_results + al_rool_morning_results + early_aluminum_rod_results
                                + discard_aluminum_results + late_aluminum_rod_results + changsha_aluminum_roll_results)
    result_df = plan_to_result(time_plan_df)

    drivers_list = driver_df[~driver_df['driver_name'].isin(assigned_drivers)]['driver_name']
    vehicles_list = vehicle_df[~vehicle_df['vehicle_id'].isin(assigned_vehicles) & vehicle_df['type'].isin(['SCANIA','奔驰','解放','厢车'])]
    print(result_df)
    result_df.to_excel('每日排班分配结果.xlsx', index=False)

    return result_df, assigned_drivers, assigned_vehicles, drivers_list, vehicles_list
